#include "stdafx.hpp"
#include "ColligerePrefDialog.hpp"
#include "ColligereApp.hpp"
#include "ColligereConfigHandler.hpp"
// For the LanguageClientData
#include "ColligereLanguageSelectionDlg.hpp"

IMPLEMENT_DYNAMIC_CLASS ( col::PreferencesDialog, wxDialog );

col::PreferencesDialog::PreferencesDialog ( wxFrame *pParent )
{
	wxXmlResource::Get()->LoadDialog ( this, pParent, "ID_Dialog_Preferences" );

	wxIcon cfg;
	cfg.CopyFromBitmap ( wxGetApp().GetIcon ( ColligereApp::IconIndex::Configure ) );
	wxASSERT ( cfg.IsOk() );
	SetIcon ( cfg );

	mpDefaultDbCtrl = XRCCTRL ( *this, "ID_TextCtrl_DefaultDb", ColligereTextCtrl );
	mpGenSettingsCtrl = XRCCTRL ( *this, "ID_CheckListBox_GenSettings", wxCheckListBox );
	mpDbSyncTypeCtrl = XRCCTRL ( *this, "ID_ComboBox_SyncType", ColligereComboBox );
	mpDbAutoSaveCtrl = XRCCTRL ( *this, "ID_CheckBox_AutoSaveDb", wxCheckBox );
	mpDbAutoVacuumCtrl = XRCCTRL ( *this, "ID_CheckBox_AutoVacuum", wxCheckBox );
	mpDbCompressionLevelCtrl = XRCCTRL ( *this, "ID_ComboBox_CompressionLevel",
		ColligereComboBox );

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	langs->Append ( _("English (Default)"), wxGetApp().GetIcon 
		( ColligereApp::IconIndex::FlagUs ), new LanguageClientData ( wxLANGUAGE_ENGLISH ) );

	langs->Append ( _("Finnish"), wxGetApp().GetIcon 
		( ColligereApp::IconIndex::FlagFi ), new LanguageClientData ( wxLANGUAGE_FINNISH ) );
	
	ConnectEventHandlers();

	LoadSettings();
}

col::PreferencesDialog::~PreferencesDialog()
{
	SaveControlValues();
}

void col::PreferencesDialog::ConnectEventHandlers()
{
	Connect ( XRCID ( "wxID_OK" ), wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler ( PreferencesDialog::OnButtonOk ) );
	Connect ( XRCID ( "ID_Button_BrowseDefaultDb" ), wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler ( PreferencesDialog::OnButtonBrowseDefaultDb ) );
	Connect ( XRCID ( "ID_Button_ResetDefaults" ), wxEVT_COMMAND_BUTTON_CLICKED,
		wxCommandEventHandler ( PreferencesDialog::OnButtonResetDefaults ) );;
}

void col::PreferencesDialog::LoadVarToGenSettingCheckListBox ( wxUint32 varId )
{
	ConfigVariable var;
	ConfigHandler::Get().GetVar ( varId, var );
	const wxUint32 idx = mpGenSettingsCtrl->Append ( var.GetDescription() );
	mpGenSettingsCtrl->Check ( idx, ConfigHandler::Get().IsEnabled ( var.GetId() ) );
	mGenSettingsItemData[idx] = var.GetId();
}

void col::PreferencesDialog::LoadSettings()
{
	using namespace std;

	typedef ConfigVariable cv;

	ConfigHandler &cfgh = ConfigHandler::Get();

	// Load the "General" page settings.

	mpGenSettingsCtrl->Clear();

	ConfigVariable var;

	LoadVarToGenSettingCheckListBox ( cv::AskBeforeApplyingValues );
	LoadVarToGenSettingCheckListBox ( cv::AskBeforeExiting );
	LoadVarToGenSettingCheckListBox ( cv::SaveLayoutOnExit );
	LoadVarToGenSettingCheckListBox ( cv::DumpLogToFileOnExit );
	LoadVarToGenSettingCheckListBox ( cv::ShowToolTips );
	LoadVarToGenSettingCheckListBox ( cv::DisableAutoComplete );

	long cur_lang = -1;
	ConfigHandler::Get().GetValue ( ConfigVariable::Language, cur_lang );

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	for ( wxUint32 i = 0; i < langs->GetCount(); ++i )
	{
		const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
			( langs->GetClientObject (i) );

		if ( lang_data->GetLanguage() == cur_lang ) 
		{
			langs->SetSelection(i);
			break;
		}
	}

	// Load the "Database" page settings.

	const wxString sync_type ( cfgh.GetValue ( cv::DatabaseSyncType ) );

	const wxArrayString sync_values ( mpDbSyncTypeCtrl->GetStrings() );

	for ( wxUint32 sync_it = 0; sync_it < sync_values.GetCount(); ++sync_it )
	{
		if ( sync_values[sync_it].StartsWith ( sync_type ) )
		{
			mpDbSyncTypeCtrl->SetStringSelection ( sync_values[sync_it] );
			break;
		}
	}

	mpDefaultDbCtrl->SetValue ( cfgh.GetValue ( cv::DefaultDatabase ) );

	long compr_level = 1;
	cfgh.GetValue ( cv::DatabaseCompressionLevel, compr_level );
	mpDbCompressionLevelCtrl->SetStringSelection ( wxString() << compr_level ); 
	
	mpDbAutoSaveCtrl->SetValue ( cfgh.IsEnabled ( cv::SaveDatabaseOnClose ) );
	mpDbAutoVacuumCtrl->SetValue ( cfgh.IsEnabled ( cv::AutoVacuumDatabase ) );

	// Load the "FreeDb" page settings.

	XRCCTRL ( *this, "ID_TextCtrl_ServerAddress", 
		wxTextCtrl )->SetValue ( cfgh.GetValue ( cv::FreeDbServerAddr ) );
	XRCCTRL ( *this, "ID_TextCtrl_Email", 
		wxTextCtrl )->SetValue ( cfgh.GetValue ( cv::FreeDbUserEmail ) );
	XRCCTRL ( *this, "ID_CheckBox_AutoSetFormat", 
		wxCheckBox )->SetValue ( cfgh.IsEnabled ( cv::FreeDbAutoSetFormatToCd ) );
}

void col::PreferencesDialog::SaveControlValues()
{
	typedef ConfigVariable cv;

	ConfigHandler &cfgh = ConfigHandler::Get();

	// Save the "General" page settings.

	for ( wxUint32 i = 0; i < mpGenSettingsCtrl->GetCount(); ++i )
	{
		cfgh.SetValue ( mGenSettingsItemData[i], mpGenSettingsCtrl->IsChecked(i) );
	}

	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
		( langs->GetClientObject ( langs->GetSelection() ) );
	wxASSERT ( lang_data );

	cfgh.SetValue ( cv::Language, lang_data->GetLanguage() );


	// Save the "Database" page settings.

	const wxString sync_type ( mpDbSyncTypeCtrl->GetStringSelection() );

	cfgh.SetValue ( cv::DatabaseSyncType, sync_type.empty() ? "OFF" 
		: sync_type.BeforeFirst (' ') );


	const wxString compr_level ( mpDbCompressionLevelCtrl->GetStringSelection() );

	wxASSERT ( !compr_level.empty() );

	long lvl = -1;
	compr_level.ToLong ( &lvl );
	cfgh.SetValue ( cv::DatabaseCompressionLevel, lvl != -1 ? lvl : 9 );
	
	cfgh.SetValue ( cv::DefaultDatabase, mpDefaultDbCtrl->GetValue() );
	cfgh.SetValue ( cv::SaveDatabaseOnClose, mpDbAutoSaveCtrl->IsChecked() );
	cfgh.SetValue ( cv::AutoVacuumDatabase, mpDbAutoVacuumCtrl->IsChecked() );

	// Save the "FreeDb" settings

	cfgh.SetValue ( cv::FreeDbAutoSetFormatToCd, XRCCTRL ( *this, "ID_CheckBox_AutoSetFormat", 
		wxCheckBox )->IsChecked() );
	cfgh.SetValue ( cv::FreeDbServerAddr, XRCCTRL ( *this, "ID_TextCtrl_ServerAddress", 
		wxTextCtrl )->GetValue() );
	cfgh.SetValue ( cv::FreeDbUserEmail, XRCCTRL ( *this, "ID_TextCtrl_Email", 
		wxTextCtrl )->GetValue() );
}

////////////////////////////////////////////////////////////
// Event Handlers
////////////////////////////////////////////////////////////

void col::PreferencesDialog::OnButtonBrowseDefaultDb ( wxCommandEvent & )
{
	wxFileDialog dlg ( this, _("Choose a file"), empty_string, 
		empty_string, _( "All Files (*.*)|*.*|COL Files (*.col)|*.col" ),
		wxFD_OPEN | wxFD_FILE_MUST_EXIST );

	if ( dlg.ShowModal() == wxID_OK )
	{
		mpDefaultDbCtrl->ChangeValue ( dlg.GetPath() );
	}
}

void col::PreferencesDialog::OnButtonResetDefaults ( wxCommandEvent & )
{
	if ( wxMessageBox (  _( "Are you sure that you wish to reset all "\
		"values to their defaults?" ) , _("Reset?"), 
		wxICON_QUESTION | wxYES_NO, this ) == wxYES )
	{
		ConfigHandler::Get().WriteDefaults ( true );
		LoadSettings();
	}
}

void col::PreferencesDialog::OnButtonOk ( wxCommandEvent &rEvent )
{
	wxBitmapComboBox *langs = XRCCTRL ( *this, "ID_BitmapComboBox_Language",
		wxBitmapComboBox );

	const LanguageClientData *lang_data = dynamic_cast < const LanguageClientData * > 
		( langs->GetClientObject ( langs->GetSelection() ) );
	wxASSERT ( lang_data );

	long prev_lang = -1;
	ConfigHandler::Get().GetValue ( ConfigVariable::Language, prev_lang );
	wxASSERT ( prev_lang != -1 );

	if ( lang_data->GetLanguage() != prev_lang )
	{
		wxLogMessage ( _("Please restart the application "\
			"for the language settings to take effect.") );
	}
	SaveControlValues();
	rEvent.Skip();
}